package order

import (
	"encoding/json"
	"errors"
	"fmt"
	"gorm.io/gorm"
	"time"

	"gitcode.com/G-YT/iHealth25/server/global"
	"gitcode.com/G-YT/iHealth25/server/model/order"
	"gitcode.com/G-YT/iHealth25/server/model/order/request"
	"gitcode.com/G-YT/iHealth25/server/model/product"
	"gitcode.com/G-YT/iHealth25/server/model/user"
	"go.uber.org/zap"
)

type OrderService struct{}

// DeleteOrder 删除订单（仅允许删除未支付订单）
func (o *OrderService) DeleteOrder(ID uint) (err error) {
	// 先查询订单状态
	var orderInfo order.Order
	err = global.GVA_DB.Where("id = ?", ID).First(&orderInfo).Error
	if err != nil {
		return fmt.Errorf("订单不存在")
	}

	// 检查订单状态，只能删除未支付的订单
	if orderInfo.Status != order.OrderStatusPending {
		return fmt.Errorf("只能删除未支付的订单")
	}

	err = global.GVA_DB.Delete(&order.Order{}, "id = ?", ID).Error
	return err
}

// BatchDeleteOrder 批量删除订单
func (o *OrderService) BatchDeleteOrder(req request.BatchDeleteOrderRequest) (err error) {
	db := global.GVA_DB.Model(&order.Order{})

	// 构建查询条件
	if len(req.IDs) > 0 {
		db = db.Where("id IN ?", req.IDs)
	}
	if req.StartTime != nil {
		db = db.Where("created_at >= ?", req.StartTime)
	}
	if req.EndTime != nil {
		db = db.Where("created_at < ?", req.EndTime)
	}
	if req.UserName != nil && *req.UserName != "" {
		db = db.Where("user_name LIKE ?", "%"+*req.UserName+"%")
	}
	if req.Status != nil {
		db = db.Where("status = ?", *req.Status)
	}
	if req.OrderNo != nil && *req.OrderNo != "" {
		db = db.Where("order_no LIKE ?", "%"+*req.OrderNo+"%")
	}

	// 只允许删除未支付的订单
	db = db.Where("status = ?", order.OrderStatusPending)

	// 执行删除
	err = db.Delete(&order.Order{}).Error
	return err
}

// GetOrder 根据ID获取订单
func (o *OrderService) GetOrder(ID uint) (order order.Order, err error) {
	err = global.GVA_DB.Preload("User.HealthManager").Preload("User.ProvinceInfo").Preload("User.CityInfo").Preload("User.AreaInfo").Where("id = ?", ID).First(&order).Error
	return
}

// GetOrderInfoList 分页获取订单列表（管理端）
func (o *OrderService) GetOrderInfoList(info request.OrderSearch) (list []order.Order, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	// 创建db
	db := global.GVA_DB.Model(&order.Order{})
	var orders []order.Order

	// 时间范围筛选
	if info.StartTime != nil && info.EndTime != nil {
		db = db.Where("created_at BETWEEN ? AND ?", *info.StartTime, *info.EndTime)
	}

	// 用户名称筛选
	if info.UserName != nil && *info.UserName != "" {
		db = db.Where("user_name LIKE ?", "%"+*info.UserName+"%")
	}

	// 商品名称筛选
	if info.ProductName != nil && *info.ProductName != "" {
		db = db.Where("product_name LIKE ?", "%"+*info.ProductName+"%")
	}

	// 订单编号筛选
	if info.OrderNo != nil && *info.OrderNo != "" {
		db = db.Where("order_no = ?", *info.OrderNo)
	}

	// 商户订单号筛选
	if info.OutTradeNo != nil && *info.OutTradeNo != "" {
		db = db.Where("out_trade_no = ?", *info.OutTradeNo)
	}

	// 微信支付订单号筛选
	if info.TransactionId != nil && *info.TransactionId != "" {
		db = db.Where("transaction_id = ?", *info.TransactionId)
	}

	// 订单状态筛选
	if info.Status != nil {
		db = db.Where("status = ?", *info.Status)
	}

	// 商品类型筛选
	if info.ProductType != nil {
		db = db.Where("product_type = ?", *info.ProductType)
	}

	err = db.Count(&total).Error
	if err != nil {
		return
	}

	// 排序
	db = db.Order("created_at desc")

	if limit != 0 {
		db = db.Limit(limit).Offset(offset)
	}
	err = db.Preload("User.HealthManager").Preload("User.ProvinceInfo").Preload("User.CityInfo").Preload("User.AreaInfo").Find(&orders).Error
	return orders, total, err
}

// GetUserOrderList 获取用户订单列表
func (o *OrderService) GetUserOrderList(userID uint, info request.UserOrderListRequest) (list []order.Order, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	// 创建db
	db := global.GVA_DB.Model(&order.Order{}).Where("user_id = ?", userID)
	var orders []order.Order

	// 时间范围筛选
	if info.StartTime != nil && info.EndTime != nil {
		db = db.Where("created_at BETWEEN ? AND ?", *info.StartTime, *info.EndTime)
	}

	err = db.Count(&total).Error
	if err != nil {
		return
	}

	// 排序
	db = db.Order("created_at desc")

	if limit != 0 {
		db = db.Limit(limit).Offset(offset)
	}
	err = db.Preload("User.HealthManager").Preload("User.ProvinceInfo").Preload("User.CityInfo").Preload("User.AreaInfo").Find(&orders).Error
	return orders, total, err
}

// CreatePayOrderWithSpecs 创建支付订单（参考用户提供的方法）
func (o *OrderService) CreatePayOrderWithSpecs(userId, productId uint, quantity uint, selectedSpecs map[string]interface{}) (OrderDetails *order.Order, err error) {
	// 参数验证
	if userId == 0 {
		return nil, errors.New("用户ID不能为空")
	}
	if productId == 0 {
		return nil, errors.New("商品ID不能为空")
	}
	if quantity == 0 {
		return nil, errors.New("商品数量必须大于0")
	}

	// 获取商品信息
	var productInfo product.Product
	productInfoErr := global.GVA_DB.Where("id = ? AND status = ?", productId, true).First(&productInfo).Error
	if errors.Is(productInfoErr, gorm.ErrRecordNotFound) {
		return nil, fmt.Errorf("商品不存在或已下架，商品ID: %d", productId)
	}
	if productInfoErr != nil {
		global.GVA_LOG.Error("查询商品信息失败", zap.Error(productInfoErr), zap.Uint("productId", productId))
		return nil, fmt.Errorf("查询商品信息失败: %v", productInfoErr)
	}

	// 获取用户信息
	var userinfo user.User
	userinfoErr := global.GVA_DB.Where("id = ?", userId).First(&userinfo).Error
	if errors.Is(userinfoErr, gorm.ErrRecordNotFound) {
		return nil, fmt.Errorf("用户不存在，用户ID: %d", userId)
	}
	if userinfoErr != nil {
		global.GVA_LOG.Error("查询用户信息失败", zap.Error(userinfoErr), zap.Uint("userId", userId))
		return nil, fmt.Errorf("查询用户信息失败: %v", userinfoErr)
	}
	// 解析商品规格
	var specification ProductSpecification
	if productInfo.Specification != nil {
		juErr := json.Unmarshal(productInfo.Specification, &specification)
		if juErr != nil {
			global.GVA_LOG.Error("商品规格数据解析失败", zap.Error(juErr), zap.Uint("productId", productId))
			return nil, fmt.Errorf("商品规格数据解析失败: %v", juErr)
		}
	}

	// 转换selectedSpecs类型
	selectedSpecsMap := make(map[string]string)
	for key, value := range selectedSpecs {
		if str, ok := value.(string); ok {
			selectedSpecsMap[key] = str
		} else {
			global.GVA_LOG.Warn("规格参数类型转换失败", zap.String("key", key), zap.Any("value", value))
		}
	}

	// 验证并计算价格
	unitPrice, sku, usErr := o.calculatePriceFromSelectedSpecs(&specification, selectedSpecsMap)
	if usErr != nil {
		global.GVA_LOG.Error("规格选择错误", zap.Error(usErr), zap.Any("selectedSpecs", selectedSpecsMap))
		return nil, fmt.Errorf("规格选择错误: %v", usErr)
	}

	// 检查库存
	csErr := o.checkStock(&specification, selectedSpecsMap, quantity)
	if csErr != nil {
		global.GVA_LOG.Error("库存检查失败", zap.Error(csErr), zap.Uint("quantity", quantity))
		return nil, fmt.Errorf("库存不足: %v", csErr)
	}
	// 生成订单号（以iH开头）
	orderNo := fmt.Sprintf("iH%d%06d", time.Now().Unix(), time.Now().Nanosecond()%1000000)
	outTradeNo := fmt.Sprintf("OUT%d%06d", time.Now().Unix(), time.Now().Nanosecond()%1000000)
	// 计算总金额
	totalAmount := unitPrice * float64(quantity)
	// 序列化用户选择的规格
	selectedSpecsJSON, jmErr := json.Marshal(selectedSpecs)
	if jmErr != nil {
		return nil, errors.New("规格数据序列化失败")
	}
	selectedSpecsStr := string(selectedSpecsJSON)
	// 确定商品类型
	var productType uint = order.ProductTypePhysical
	if productInfo.ProductType == 2 {
		productType = order.ProductTypeVirtual
	}
	// 使用数据库事务确保数据一致性
	tx := global.GVA_DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
			global.GVA_LOG.Error("创建订单时发生panic", zap.Any("error", r))
		}
	}()

	// 创建订单
	productIdInt := int(productId)
	OrderDetails = &order.Order{
		OrderNo:       &orderNo,
		OutTradeNo:    outTradeNo,
		UserId:        userId,
		ProductId:     &productIdInt,
		ProductName:   productInfo.Name,
		ProductType:   productType,
		ProductSku:    &sku,
		SelectedSpecs: &selectedSpecsStr,
		UnitPrice:     &unitPrice,
		Amount:        &totalAmount,
		Quantity:      quantity,
		Status:        order.OrderStatusPending,
		PaymentType:   order.PaymentTypeWechat,
		TradeState:    order.TradeStateNotPay,
	}

	err = tx.Create(OrderDetails).Error
	if err != nil {
		tx.Rollback()
		global.GVA_LOG.Error("创建订单失败", zap.Error(err), zap.Uint("userId", userId), zap.Uint("productId", productId))
		return nil, fmt.Errorf("创建订单失败: %v", err)
	}

	// 提交事务
	if err = tx.Commit().Error; err != nil {
		global.GVA_LOG.Error("提交订单创建事务失败", zap.Error(err))
		return nil, fmt.Errorf("保存订单失败: %v", err)
	}

	// 重新查询订单并预加载User信息及其关联数据
	err = global.GVA_DB.Preload("User").Preload("User.HealthManager").Preload("User.Division").Preload("User.UrgentCard").Preload("User.ProvinceInfo").Preload("User.CityInfo").Preload("User.AreaInfo").Where("id = ?", OrderDetails.ID).First(OrderDetails).Error
	if err != nil {
		global.GVA_LOG.Error("查询订单详情失败", zap.Error(err), zap.Uint("orderId", OrderDetails.ID))
		return nil, fmt.Errorf("查询订单详情失败: %v", err)
	}

	global.GVA_LOG.Info("订单创建成功", zap.Uint("orderId", OrderDetails.ID), zap.String("orderNo", orderNo), zap.Uint("userId", userId), zap.Uint("productId", productId))
	return OrderDetails, nil
}

// ProductSpecification 商品规格结构体
type ProductSpecification struct {
	Attributes []SpecificationAttribute `json:"attributes"`
}

// SpecificationAttribute 规格属性结构体
type SpecificationAttribute struct {
	Name   string               `json:"name"`
	Values []SpecificationValue `json:"values"`
}

// SpecificationValue 规格值结构体
type SpecificationValue struct {
	Name  string  `json:"name"`
	Price float64 `json:"price"`
	Stock uint    `json:"stock"`
	Sku   string  `json:"sku"`
}

// calculatePriceFromSelectedSpecs 根据选择的规格计算价格
func (o *OrderService) calculatePriceFromSelectedSpecs(specification *ProductSpecification, selectedSpecs map[string]string) (float64, string, error) {
	if specification == nil || len(specification.Attributes) == 0 {
		return 0, "", fmt.Errorf("商品规格信息为空")
	}

	// 基础价格
	var totalPrice float64 = 0
	var skuParts []string

	// 遍历所有规格属性
	for _, attr := range specification.Attributes {
		selectedValue, exists := selectedSpecs[attr.Name]
		if !exists {
			continue
		}

		// 查找对应的规格值
		for _, value := range attr.Values {
			if value.Name == selectedValue {
				totalPrice += value.Price
				if value.Sku != "" {
					skuParts = append(skuParts, value.Sku)
				}
				break
			}
		}
	}

	// 生成SKU
	sku := "default-sku"
	if len(skuParts) > 0 {
		sku = fmt.Sprintf("%s", skuParts[0]) // 使用第一个SKU或组合多个SKU
	}

	return totalPrice, sku, nil
}

// checkStock 检查库存
func (o *OrderService) checkStock(specification *ProductSpecification, selectedSpecs map[string]string, quantity uint) error {
	if specification == nil || len(specification.Attributes) == 0 {
		return fmt.Errorf("商品规格信息为空")
	}

	// 检查每个选择的规格值的库存
	for _, attr := range specification.Attributes {
		selectedValue, exists := selectedSpecs[attr.Name]
		if !exists {
			continue
		}

		// 查找对应的规格值并检查库存
		for _, value := range attr.Values {
			if value.Name == selectedValue {
				if value.Stock < quantity {
					return fmt.Errorf("规格 %s:%s 库存不足，当前库存：%d，需要：%d", attr.Name, value.Name, value.Stock, quantity)
				}
				break
			}
		}
	}

	return nil
}
